package pers.jphoebe.quartz.config.scheduler;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import pers.jphoebe.quartz.utils.Logger;

@Configuration
// @ConditionaXXXXX 符合条件才创建该bean
@ConditionalOnProperty(name = "quartz.enabled")
public class SchedulerConfig {

    private Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    @Qualifier("h2DataSource")
    DataSource dataSource;

    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException {

        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setQuartzProperties(quartzProperties());
        factory.setOverwriteExistingJobs(true);
        factory.setJobFactory(jobFactory);
        factory.setSchedulerFactoryClass(StdSchedulerFactory.class);

        return factory;
    }

    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        /**
         * 必须加上这句，否则无法持久化
         */
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    @Bean
    public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) {
        try {
            return schedulerFactoryBean.getScheduler();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    public QuartzInitializerListener executorListener() {

        /**
         * 动态创建数据库
         */
        logger.info(null,"执行H2数据库SQL脚本");
        try {
            ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
            populator.addScript(new ClassPathResource("sql/quartz/execute.sql"));
            populator.populate(dataSource.getConnection());
        }catch (SQLException e){
            logger.error("执行H2数据库SQL脚本错误");
        }

       return new QuartzInitializerListener();
    }

}
